function Mouse() {}

Mouse.initialise = () => {
  Mouse.rawPos = new THREE.Vector2(0, 0)
  Mouse.rawMovement = new THREE.Vector2(0, 0)
  Mouse.rawPosUpdated = false
  Mouse.rawWheel = 0
  Mouse.rawWheelUpdated = false

  Mouse.pos = new THREE.Vector2(0, 0)
  Mouse.posDiff = new THREE.Vector2(0, 0)
  Mouse.wheel = 0

  Mouse.canvas = null

  Mouse.rawKeys = []
  Mouse.rawKeys[0] = new Key()
  Mouse.rawKeys[1] = new Key()
  Mouse.rawKeys[2] = new Key()

  Mouse.keys = []
  Mouse.keys[0] = new Key()
  Mouse.keys[1] = new Key()
  Mouse.keys[2] = new Key()

  document.onwheel = (e) => {
    // TODO: This
  }

  document.onmousewheel = (e) => {
    Mouse.rawWheel = e.deltaY
    Mouse.rawWheelUpdated = true
  }

  document.onmousemove = (e) => {
    if (Mouse.canvas !== null) {
      var rect = Mouse.canvas.getBoundingClientRect()
      Mouse.updatePosition(e.clientX - rect.left, e.clientY - rect.top, e.movementX, e.movementY)
    } else {
      Mouse.updatePosition(e.clientX, e.clientY, e.movementX, e.movementY)
    }
  }

  document.onmousedown = (e) => {
    Mouse.updateKey(e.which-1, Key.KEY_DOWN)
  }

  document.onmouseup = (e) => {
    Mouse.updateKey(e.which-1, Key.KEY_UP)
  }
}

Mouse.LEFT = 0
Mouse.MIDDLE = 1
Mouse.RIGHT = 2

Mouse.SENSITIVITY = 0.2

Mouse.insideCanvas = () => {
  if (Mouse.canvas === null) {
    return null
  }

  var rect = Mouse.canvas.getBoundingClientRect()
  return (Mouse.pos.x > 0 && Mouse.pos.y > 0 && Mouse.pos.x < rect.width && Mouse.pos.y < rect.height)
}

Mouse.buttonPressed = (button) => {
  return Mouse.keys[button].isPressed
}

Mouse.buttonJustPressed = (button) => {
  return Mouse.keys[button].justPressed
}

Mouse.buttonJustReleased = (button) => {
  return Mouse.keys[button].justReleased
}

Mouse.updatePosition = (x, y, xDiff, yDiff) => {
  Mouse.rawPos.set(x, y)
  Mouse.rawMovement.x += xDiff
  Mouse.rawMovement.y += yDiff
  Mouse.rawPosUpdated = true
}

Mouse.updateKey = (button, action) => {
  Mouse.rawKeys[button].update(action)
}

Mouse.update = () => {
  for (var i = 0; i < Mouse.rawKeys.length; i++) {
    if (Mouse.rawKeys[i].justPressed && Mouse.keys[i].justPressed) {
      Mouse.rawKeys[i].justPressed = false
    }

    if (Mouse.rawKeys[i].justReleased && Mouse.keys[i].justReleased) {
      Mouse.rawKeys[i].justReleased = false
    }

    Mouse.keys[i].set(Mouse.rawKeys[i].justPressed,
                      Mouse.rawKeys[i].isPressed,
                      Mouse.rawKeys[i].justReleased)
  }

  if (Mouse.rawWheelUpdated) {
    Mouse.wheel = Mouse.rawWheel
    Mouse.rawWheelUpdated = false
  } else {
    Mouse.wheel = 0
  }

  if (Mouse.rawPosUpdated) {
    Mouse.posDiff.x = Mouse.rawMovement.x
    Mouse.posDiff.y = Mouse.rawMovement.y
    Mouse.rawMovement.set(0, 0)

    Mouse.pos.x = Mouse.rawPos.x
    Mouse.pos.y = Mouse.rawPos.y

    Mouse.rawPosUpdated = false
  } else {
    Mouse.posDiff.x = 0
    Mouse.posDiff.y = 0
  }
}
